package com.ezops.dtcc;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Calendar;
import java.util.List;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class DtccPostionsFileWatcherService implements ApplicationContextAware, Runnable {
	private final Logger LOGGER = Logger.getLogger(DtccPostionsFileWatcherService.class);
	
	@SuppressWarnings("unused")
	private ApplicationContext context;
	private FpmlParser fpmlParser = null;
	private Properties props = null;
	
	private String inFilePath ;
	private String outFilePath ;
	
	public DtccPostionsFileWatcherService(FpmlParser fpmlParser ) {
		
		this.fpmlParser = fpmlParser;
	}

	public void start(){
		LOGGER.info("---Starting FileWatcher");
		//Start the service 
		Thread t = new Thread(this);
		//t.setDaemon(true);
		t.start();
		LOGGER.info("---Started FileWatcher");
		
	}
	
	public void run() {
		WatchService watcher = null;
		WatchKey watchKey = null;
		try {
			
			//Path myDir = Paths.get(props.getProperty("FILE_WATCHER_PATH"));
			
			Path myDir = Paths.get(getInFilePath());
			
			watcher = myDir.getFileSystem().newWatchService();
			myDir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE,
					StandardWatchEventKinds.ENTRY_DELETE,
					StandardWatchEventKinds.ENTRY_MODIFY);

			watchKey = watcher.take();
		} catch(Exception ex) {
			LOGGER.error("Error: " + ex.toString());
			return;
		}

		LOGGER.info("---Now watching "+ getInFilePath() +"---");
		while(watchKey!=null) {
			try {
				
				File f = new File( getInFilePath() + "\\stop");
				
				//File f = new File(props.getProperty("FILE_WATCHER_PATH")+"/"+props.getProperty("STOP_FILE_NAME"));
				
				if(f.exists() && !f.isDirectory()) {
					LOGGER.info("Quitting processing..");
					f.deleteOnExit();
					break;
				}

				List<WatchEvent<?>> events = watchKey.pollEvents();
				for (@SuppressWarnings("rawtypes") WatchEvent event : events) {
					if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
						LOGGER.info("New file dropped: "+ event.context().toString());
						//+++++++++++++ HARDCODE ++++++++++++++
						String fullPath =  getInFilePath() + "\\" + event.context().toString();
						//+++++++++++++ HARDCODE ++++++++++++++
										
						fpmlParser.readAndWrite(fullPath);
						archiveFile(event.context().toString());
					}
				}
				
				Thread.sleep(10000);
			} catch (Exception e) {
				LOGGER.error("Error: " + e.toString());
			}
		}
	}

	private boolean archiveFile(String filePath) {
		 String newFilePath = "";
		 
		try {
			
			File processedFile = new File( getInFilePath() + "\\"+filePath);
			
			File newFile = new File(props.getProperty( getOutFilePath()+ "\\" +filePath+"-"+Calendar.getInstance().getTimeInMillis()));
			newFilePath = newFile.getAbsoluteFile().getAbsolutePath();
			if (processedFile.renameTo(newFile)) {
				LOGGER.info(newFile.getAbsoluteFile().getAbsolutePath() +" move is successful..");
			}
			
		} catch (Exception e) {
			LOGGER.info(newFilePath +" move is unsuccessful..");
			return false;
		}
		return true;
	}

	@Override
	public void setApplicationContext(ApplicationContext appContext) 	throws BeansException {
		context = appContext;
		
	}

	public String getInFilePath() {
		return inFilePath;
	}

	public void setInFilePath(String inFilePath) {
		this.inFilePath = inFilePath;
	}

	public String getOutFilePath() {
		return outFilePath;
	}

	public void setOutFilePath(String outFilePath) {
		this.outFilePath = outFilePath;
	}
}
